<script setup>
import {onBeforeMount, onMounted, reactive, ref} from "vue";
import {useRoute, useRouter} from "vue-router";
import DirNewDialog from "@/components/DirNewDialog.vue";
import DirContextMenu from "@/components/DirContextMenu.vue";
import UploadFile from "@/components/UploadFile.vue";
import FileContextMenu from "@/components/FileContextMenu.vue";
import {getAvatar, postRequest} from "@/util/api";

const data = reactive({
  fileList: [],
  activeFileItemName: "",
  currentPathList: [],
  imgSrc: "",
  parentDirId: "",
});

let mainContainerWidth, mainContainerHeight;
onMounted(() => {
  const mainContainer = document.getElementsByClassName("main-container")[0];
  mainContainerWidth = mainContainer.clientWidth;
  mainContainerHeight = mainContainer.clientHeight;
});

function initDirAndFileList() {
  postRequest("/dir/getDirAndFileList", null, {
    parentDirId: Number(data.parentDirId),
  }, (res) => {
    data.activeFileItemName = "";

    const json = res.data.data;
    data.fileList = [];
    data.currentPathList = [];

    for (let i = json["dirPath"].length - 1; i >= 0; i--) {
      data.currentPathList.push({
        id: i + 1,
        name: json["dirPath"][i].dirName,
        dirId: json["dirPath"][i].dirId,
        parentDirId: json["dirPath"][i].parentDirId,
      });
    }
    for (let i = 0; i < json["dirList"].length; i++) {
      data.fileList.push({
        id: i + 1,
        name: json["dirList"][i].dirName,
        ico: "directory",
        dirId: json["dirList"][i].dirId,
        parentDirId: json["dirList"][i].parentDirId,
        createTime: json["dirList"][i].createTime,
      });
    }
    for (let i = 0; i < json["fileInfoList"].length; i++) {
      data.fileList.push({
        id: i + 1 + json["dirList"].length,
        name: json["fileInfoList"][i].fileName,
        ico: "file",
        fileId: json["fileInfoList"][i].fileId,
        dirId: json["fileInfoList"][i].dirId,
        fileMd5: json["fileInfoList"][i].fileMd5,
        fileSize: json["fileInfoList"][i].fileSize,
        createTime: json["fileInfoList"][i].createTime,
      });
    }
  });
}

const route = useRoute();
const router = useRouter();

onBeforeMount(async () => {
  data.parentDirId = route.query.dirId ? route.query.dirId : 0;
  data.imgSrc = await getAvatar();
  initDirAndFileList();
});

function enterDir(item) {
  if (item.ico === "file") {
    return;
  }
  router.push({
    path: route.path,
    query: {
      dirId: item.dirId
    }
  });
  data.parentDirId = item.dirId;
  initDirAndFileList();
}

function enterParentDir(item) {
  const dirId = item.dirId === 0 ? undefined : item.dirId;
  router.push({
    path: route.path,
    query: {
      dirId: dirId
    }
  });
  data.parentDirId = item.dirId;
  initDirAndFileList();
}

function enterLastParentDir() {
  if (data.currentPathList.length <= 1) {
    return;
  }
  enterParentDir(data.currentPathList[data.currentPathList.length - 2]);
}

function focusFileItem(item) {
  data.activeFileItemName = item.name;
  dirContextMenuRef.value.hiddenContextMenu();
  fileContextMenuRef.value.hiddenContextMenu();
}

function cancelFocus() {
  data.activeFileItemName = "";
  dirContextMenuRef.value.hiddenContextMenu();
  fileContextMenuRef.value.hiddenContextMenu();
}

const dirNewDialogRef = ref();
const dirContextMenuRef = ref();
const fileContextMenuRef = ref();
const uploadFileRef = ref();

function uploadFile() {
  uploadFileRef.value.uploadFile();
}

function openUploadDialog() {
  uploadFileRef.value.openUploadDialog();
}

function openNewDirDialog() {
  dirNewDialogRef.value.openDirNewDialog();
}

function showContextMenu(event, item) {
  event.preventDefault();
  data.activeFileItemName = item.name;

  let posX = event.clientX - 160;
  let posY = event.clientY - 10;
  if (posX + 80 >= mainContainerWidth) {
    posX = mainContainerWidth - 80;
  }
  if (posY + 120 >= mainContainerHeight) {
    posY = mainContainerHeight - 120;
  }
  if (item.ico === "directory") {
    fileContextMenuRef.value.hiddenContextMenu();
    dirContextMenuRef.value.showContextMenu({
      dir: {
        parentDirId: item.parentDirId,
        dirId: item.dirId,
        name: item.name,
        createTime: item.createTime,
      },
      posX: posX,
      posY: posY
    });
  } else if (item.ico === "file") {
    dirContextMenuRef.value.hiddenContextMenu();
    fileContextMenuRef.value.showContextMenu({
      file: {
        name: item.name,
        fileId: item.fileId,
        dirId: item.dirId,
        fileMd5: item.fileMd5,
        fileSize: item.fileSize,
        createTime: item.createTime,
      },
      posX: posX,
      posY: posY
    });
  }
}
</script>

<template>
  <div class="main-container" @click.self="cancelFocus">
    <div class="header-container">
      <i class="iconfont icon-left" @click="enterLastParentDir()"></i>
      <i class="iconfont icon-refresh" @click="initDirAndFileList"></i>
      <i class="iconfont icon-sort"></i>

      <div class="upload-new-button">
        <span class="upload" @click="uploadFile">上传</span>
        <span class="new" @click="openNewDirDialog">新建文件夹</span>
      </div>

      <div v-for="item in data.currentPathList" :key="item.id" class="current-path">
        <span @click="enterParentDir(item)">{{ item.name }}</span>
        <i class="iconfont icon-right"></i>
      </div>

      <div class="avatar">
        <img :src="data.imgSrc" alt=""/>
      </div>

      <i class="iconfont icon-download"></i>
      <i class="iconfont icon-upload" @click="openUploadDialog"></i>
    </div>

    <template v-if="data.fileList.length > 0">
      <div v-for="item in data.fileList" :key="item.id"
           :class="data.activeFileItemName === item.name ? 'single-active-file-item' : ''" class="single-file-item"
           @click="focusFileItem(item)"
           @contextmenu="showContextMenu($event, item)" @dblclick="enterDir(item)">
        <i :class="'iconfont icon-' + item.ico"></i>
        <span>{{ item.name }}</span>
      </div>
    </template>
    <template v-if="data.fileList.length === 0">
      <div class="no-data">No Data</div>
    </template>

    <DirContextMenu ref="dirContextMenuRef" :init-data="initDirAndFileList"/>
    <FileContextMenu ref="fileContextMenuRef" :init-data="initDirAndFileList"/>
    <DirNewDialog ref="dirNewDialogRef" :init-data="initDirAndFileList" :parent-dir-id="data.parentDirId"/>
    <UploadFile ref="uploadFileRef" :init-data="initDirAndFileList" :parent-dir-id="data.parentDirId"/>
  </div>
</template>

<style lang="scss" scoped>
.main-container {
  width: 100%;
  height: 100%;
  position: relative;

  .single-file-item {
    float: left;
    width: 110px;
    height: 120px;
    text-align: center;
    padding: 8px 0;

    &:hover {
      background-color: #e5f3ff;
    }

    .iconfont {
      font-size: 74px;
      color: #ffd768;
      display: block;
    }

    span {
      height: 30px;
      line-height: 30px;
      font-size: 14px;
      display: block;
      cursor: default;
      text-overflow: ellipsis;
      overflow: hidden;
      white-space: nowrap;
      padding: 0 10px;
    }
  }

  .single-active-file-item {
    background-color: #cce8ff;

    &:hover {
      background-color: #cce8ff;
    }
  }

  .no-data {
    position: absolute;
    top: 50%;
    height: 50px;
    width: 100%;
    line-height: 50px;
    transform: translateY(-50%);
    color: gray;
    text-align: center;
  }
}

.header-container {
  width: 100%;
  height: 40px;
  border-bottom: 1px solid #9f9f9f;

  .icon-right {
    transform: rotate(180deg);
  }

  .iconfont {
    width: 40px;
    height: 39px;
    text-align: center;
    line-height: 39px;
    display: block;
    float: left;
    font-size: 20px;
  }

  .iconfont:hover {
    background-color: #edf6fb;
  }

  .icon-upload {
    float: right;
    font-size: 18px;
  }

  .icon-download {
    float: right;
    font-size: 24px;
  }

  .avatar {
    float: right;
    width: 40px;
    height: 39px;
    display: flex;
    justify-content: center;
    align-items: center;

    img {
      width: 30px;
      height: 30px;
      border-radius: 50%;
    }
  }

  .upload-new-button {
    float: left;
    height: 39px;
    line-height: 39px;
    margin: 0 30px;

    .upload {
      margin-right: 15px;
      color: #409eff;

      &:hover {
        cursor: pointer;
        color: #79bbff;
      }
    }

    .new {
      color: #f56c6c;

      &:hover {
        cursor: pointer;
        color: #f89898;
      }
    }
  }

  .current-path {
    max-width: 600px;
    width: fit-content;
    height: 39px;
    line-height: 39px;
    float: left;

    i {
      float: left;
      font-size: 16px;
    }

    i:hover {
      background-color: white;
    }

    span {
      float: left;
    }

    span:hover {
      cursor: pointer;
      color: #06a8fd;
    }
  }
}
</style>